package com.javacoo.fastdfs.client.internal.template;

import java.util.Optional;

import com.javacoo.fastdfs.client.api.pool.StorageClient1Wrapper;
import com.javacoo.fastdfs.client.api.pool.StorageClient1WrapperPool;
import com.javacoo.fastdfs.client.api.pool.StorageClient1WrapperPoolFactory;
import com.javacoo.fastdfs.client.api.template.Executor;
import com.javacoo.fastdfs.client.api.template.FastDFSTemplate;
import com.javacoo.fastdfs.client.config.FastDFSConfig;
import com.javacoo.fastdfs.client.exception.JccfcFastDFSException;

import lombok.extern.slf4j.Slf4j;

/**
 *  FastDFS操作模板类默认实现
 * @author: duanyong@jccfc.com
 * @since: 2020/4/30 9:57
 */
@Slf4j
public class DefaultFastDFSTemplate implements FastDFSTemplate {
    /**FastDFS配置*/
    private FastDFSConfig fastDFSConfig;
    /** StorageClient1Wrapper对象池*/
    private StorageClient1WrapperPool storageClient1WrapperPool;

    /**
     * 初始化
     * <p>说明:</p>
     * @param fastDFSConfig FastDFS配置类
     * @author duanyong@jccfc.com
     * @date 2020/5/3 15:48
     */
    @Override
    public DefaultFastDFSTemplate init(FastDFSConfig fastDFSConfig) throws Exception{
        this.fastDFSConfig = fastDFSConfig;
        this.storageClient1WrapperPool = StorageClient1WrapperPoolFactory.create().init(fastDFSConfig);
        return this;
    }

    /**
     * 运行方法
     * <p>说明:</p>
     * <li></li>
     * @author duanyong@jccfc.com
     * @date  2020/4/30 16:20
     * @param executor 执行器
     * @throws JccfcFastDFSException
     * @return Optional<R>
     */
    @Override
    public <R> Optional<R> run(Executor<R> executor) throws JccfcFastDFSException {
        StorageClient1Wrapper storageClient1Wrapper = getClient();
        if (storageClient1Wrapper == null) {
            return null;
        }
        try {
            return executor.execute(storageClient1Wrapper.getStorageClient1());
        } catch (Exception e) {
            throw new JccfcFastDFSException(e.getMessage(), e, 0);
        } finally {
            releaseClient(storageClient1Wrapper);
        }
    }

    /**
     * 获取FastDFS配置类
     * <p>说明:</p>
     * <li></li>
     *
     * @author duanyong@jccfc.com
     * @date 2020/5/3 15:51
     */
    @Override
    public FastDFSConfig getFastDFSConfig() {
        return this.fastDFSConfig;
    }

    /**
     * 从连接池中获StorageClient
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:40
     * @return: org.csource.fastdfs.StorageClient1
     */
    private StorageClient1Wrapper getClient() {
        StorageClient1Wrapper client = null;
        //重试次数
        AtomicInteger retryCount = new AtomicInteger(this.fastDFSConfig.getRetryCount());
        log.info("getClient->retryCount->{}",retryCount.get());
        while (client == null && retryCount.decrementAndGet() >= 0) {
            try {
                client = storageClient1WrapperPool.getClient();
            } catch (Exception e) {
                storageClient1WrapperPool.dumpPoolInfo();
                log.warn("线程->{},从对象池中获client异常,还可以重试:{}次",Thread.currentThread().getName(),retryCount.get(),e);
            }
        }
        return client;
    }
    /**
     * 释放StorageClient
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:40
     * @param storageClient1Wrapper:
     * @return: void
     */
    private void releaseClient(StorageClient1Wrapper storageClient1Wrapper) {
        storageClient1WrapperPool.releaseClient(storageClient1Wrapper);
    }


}
